package com.zq.it.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.zq.it.pojo.Page;

//import org.hibernate.Query;

public class BaseDao<T> extends HibernateDaoSupport {

	@SuppressWarnings("unchecked")
	public void deleteEntity(final String hql) {
		getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				return query.executeUpdate();
			}
		});
	}
	protected List findByPage(final int offset, final int pageSize,
			final String hql) {
		List list = null;
		try {
			list = this.getHibernateTemplate()
					.executeFind(new HibernateCallback() {
						@Override
						public Object doInHibernate(Session session)
								throws HibernateException, SQLException {
							Query query = session.createQuery(hql);
							query.setFirstResult(offset);
							query.setMaxResults(pageSize);
							List list = query.list();
							return list;
						}
					});
		} catch (Exception e) {
		}
		return list;
	}
	public List findEtyByHql(final String hql) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				return query.list();
			}
		});
	}

	public List findEtyBySQL(final String sql) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				return session.createSQLQuery(sql).list();
			}
		});
	}

	public List findEtyByFetchMode(final Class c, final String modeStr,
			final String sql) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria query = session.createCriteria(c)
						.add(Restrictions.sqlRestriction(sql))
						.setFetchMode(modeStr, org.hibernate.FetchMode.JOIN);
				return query.list();
			}
		});
	}

	/**
	 * @author Administrator
	 */
	public Session getCurSession() {
		return getHibernateTemplate().getSessionFactory().getCurrentSession();
	}

	public List getPage(final int currentPage, final String hql) {

		return getHibernateTemplate()
				.executeFind(new HibernateCallback<Object>() {
					@Override
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						int num = query.list().size();
						query.setFirstResult((currentPage - 1) * 30);
						query.setMaxResults(30);
						List list = query.list();
						list.add(num);
						return list;
					}
				});

	}

    @SuppressWarnings("unchecked")
    public List<T> getList(Page page, String hql, String name, Object value) {
        try {
            Query query = setQuery(hql, name, value);
            query.setFirstResult((page.getOffSet()));
            query.setMaxResults(page.getPageSize());
            query.setCacheable(true);
            return query.list();
        } catch (RuntimeException re) {
            throw re;
        }
    }

    public List<T> findByCriteria(Class<T> t, String fetchMode1, String parmeter, Object value, Page page) {
        DetachedCriteria criteria = DetachedCriteria.forClass(t);
        criteria.add(Restrictions.eq(parmeter, value)).addOrder(Order.desc("createTime"));
        criteria.setFetchMode(fetchMode1, FetchMode.JOIN).setResultTransformer(criteria.DISTINCT_ROOT_ENTITY);
        return getHibernateTemplate().findByCriteria(criteria, page.getOffSet(), page.getPageSize());
    }

    public int getCountByHql(String hql) {
        Query query = getSession().createQuery(hql);
        return ((Number) query.uniqueResult()).intValue();

    }

    public List<T> findByHql(Page page, String hql) {
        try {
            Query query = getSession().createQuery(hql);
            query.setFirstResult((page.getOffSet()));
            query.setMaxResults(page.getPageSize());
            query.setCacheable(true);
            return query.list();
        } catch (RuntimeException re) {
            throw re;
        }
    }

    public List<T> findAll(String hql) {
        return getHibernateTemplate().find(hql);
    }

    @SuppressWarnings("unchecked")
    public T getById(long id, Class<?> c) {
        return (T) getHibernateTemplate().get(c, id);
    }

    public void add(T t) {
        // TODO Auto-generated method stub
        getHibernateTemplate().save(t);
    }

    public void delete(T t) {
        // TODO Auto-generated method stub
        getHibernateTemplate().delete(t);
    }

    public void update(T t) {
        // TODO Auto-generated method stub
        getHibernateTemplate().update(t);
    }

    public int getCount(String hql, String name, Object value) {
        try {
            Query query = setQuery(hql, name, value);
            return ((Number) query.uniqueResult()).intValue();
        } catch (RuntimeException re) {
            throw re;
        }
    }

    private Query setQuery(String hql, String name, Object value) {
        Query query = null;
        if (null != value && !"".equals(value)) {
            hql += "where t." + name + " like :name";
            query = getSession().createQuery(hql);
            query.setParameter("name", "%" + value + "%");
        } else {
            query = getSession().createQuery(hql);
        }
        return query;
    }
}
